package com.bruce.tool.netty.socket.netty.chat3;

import com.bruce.tool.common.util.LogUtils;
import com.bruce.tool.common.util.string.JsonUtils;
import com.bruce.tool.common.util.string.MapHandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * Keep reconnecting to the server while printing out the current uptime and
 * connection attempt getStatus.
 */
@Slf4j
@Sharable
public class ChatAHandler extends ChannelInboundHandlerAdapter{

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        String message = toString(msg);
        if(message.contains("pong")){
            LogUtils.info(log,"心跳检测:{}",message);
        }
    }

    @Override
    public void channelInactive(final ChannelHandlerContext ctx) {
//        ctx.channel().eventLoop().schedule(ChatA::connect, ChatA.RECONNECT_DELAY, TimeUnit.SECONDS);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        if (!(evt instanceof IdleStateEvent)) {
            return;
        }

        IdleStateEvent e = (IdleStateEvent) evt;
        switch(e.state()){
            case READER_IDLE:
                handleReaderIdle(ctx);
                break;
            case WRITER_IDLE:
                handleWriterIdle(ctx);
                break;
            case ALL_IDLE:
                handleAllIdle(ctx);
                break;
            default:
                break;
        }
    }

    /**状态为读闲置**/
    private void handleReaderIdle(ChannelHandlerContext ctx) {
        ctx.close();
    }

    /**状态为写闲置**/
    private void handleWriterIdle(ChannelHandlerContext ctx) {
        // do nothing
    }

    /**读写均闲置**/
    private void handleAllIdle(ChannelHandlerContext ctx) {
        Map body = MapHandler.build().add("ping","渠道A");
        String message = JsonUtils.objToStr(body);
        ctx.writeAndFlush(Unpooled.copiedBuffer(message.getBytes()));
    }

    private String toString(Object data) {
        if( !(data instanceof ByteBuf) ){
            return "";
        }
        ByteBuf buf = (ByteBuf)data;
        String str;
        if(buf.hasArray()) { // 处理堆缓冲区
            str = new String(buf.array(), buf.arrayOffset() + buf.readerIndex(), buf.readableBytes());
        } else { // 处理直接缓冲区以及复合缓冲区
            byte[] bytes = new byte[buf.readableBytes()];
            buf.getBytes(buf.readerIndex(), bytes);
            str = new String(bytes, 0, buf.readableBytes());
        }
        return str;
    }
}